package com.ctg.behavior.calc.impala.builder.retentions;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.calc.common.CtCalcDate;
import com.ctg.behavior.calc.impala.report.retentions.CtRetentionsReport;
import com.ctg.behavior.calc.utils.CtCalcDaysUtils;
import com.ctg.behavior.common.consts.CtCalcConsts;
import com.ctg.behavior.common.retentions.CtRetentionsCalcBody;
import com.ctg.behavior.utils.CtDateUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtRetentionsReportBuilder {

	/****************************************************************
	 * @apiNote: 1.示例说明：在8-23进行App元素点击的964人中,有32人在第1天(8-24)进行了App元素点击,占比3.32%
	 * @apiNote: 2.示例说明：在8-23进行App元素点击的964人中,有23人在第2天(8-25)进行了App元素点击,占比2.39%
	 * @apiNote: 3.cellDays是记录第几天的信息; cellWeeks是记录第几周的信息; cellMonths是记录第几月的信息;
	 * @apiNote: 4.每个CtRetentionsReport就是记录的要进行的【第几天/周/月】分析计算的请求信息
	 * @apiNote: 5.本ReportBuilder的作用：据Request中的fromDate与toDate,
	 *           拆分为有序时间顺序【第几天/周/月】的计算集合
	 */
	public List<CtRetentionsReport> doBuilder(CtRetentionsCalcBody calcBody) {

		log.info("calcBody={}", JSON.toJSONString(calcBody));

		List<CtRetentionsReport> calcReports = new ArrayList<>();

		String fromDate = calcBody.getFromDate();
		String toDate = calcBody.getToDate();
		String todayDate = CtDateUtils.getCurrentDate(CtDateUtils.YYYY_MM_DD);
		log.info("fromDate={},toDate={},todayDate={}", fromDate, toDate, todayDate);

		if (CtCalcConsts.UNIT_TYPE_DAY.equalsIgnoreCase(calcBody.getUnit())) {
			List<CtCalcDate> baseDays = CtCalcDaysUtils.listCalcDays(fromDate, toDate);
			for (CtCalcDate whichDate : baseDays) {
				
				String fromDateDay = CtDateUtils.dateToString(whichDate.getFromDate(), CtDateUtils.YYYY_MM_DD);
				String toDateDay = CtDateUtils.dateToString(whichDate.getToDate(), CtDateUtils.YYYY_MM_DD);

				List<CtCalcDate> cellDays = CtCalcDaysUtils.listCalcDays(fromDateDay, todayDate);
				if (cellDays.isEmpty()) {
					continue;
				}
				if(cellDays.size() > 7) {
					cellDays = new ArrayList<>(cellDays.subList(0, 7));
				}
				CtRetentionsReport oneReport = this.copyBody(calcBody);
				calcReports.add(oneReport);
				// 原始RequestBody fromDate到toDate中的某一天
				oneReport.setWhichDay(fromDateDay);
				// 本“whichDay”的最大的“【第几天/周/月】”
				oneReport.setMaxCellIndex(cellDays.size());
				// 本cellDay对应的第一事件的开始与结束日期
				oneReport.setTheFirstEventFromDate(fromDateDay);
				oneReport.setTheFirstEventToDate(toDateDay);
				// 本ROW的所有Cell的Date开始与结束时间
				oneReport.setCellDates(cellDays);
			}
		} else if (CtCalcConsts.UNIT_TYPE_WEEK.equalsIgnoreCase(calcBody.getUnit())) {
			List<CtCalcDate> weeks = CtCalcDaysUtils.listCalcWeeks(fromDate, toDate);
			for (CtCalcDate whichDate : weeks) {
				
				String fromDateDay = CtDateUtils.dateToString(whichDate.getFromDate(), CtDateUtils.YYYY_MM_DD);
				String toDateDay = CtDateUtils.dateToString(whichDate.getToDate(), CtDateUtils.YYYY_MM_DD);
				
				List<CtCalcDate> cellWeeks = CtCalcDaysUtils.listCalcWeeks(fromDateDay, todayDate);
				if(cellWeeks.size() > 4) {
					cellWeeks = new ArrayList<>(cellWeeks.subList(0, 4));
				}
				
				CtRetentionsReport oneReport = this.copyBody(calcBody);
				calcReports.add(oneReport);

				// 原始RequestBody fromDate到toDate中的某一天
				oneReport.setWhichDay(fromDateDay);
				oneReport.setMaxCellIndex(cellWeeks.size());

				// 本cellDay对应的第一事件的开始与结束日期
				oneReport.setTheFirstEventFromDate(fromDateDay);
				oneReport.setTheFirstEventToDate(toDateDay);

				// 本ROW的所有Cell的Date开始与结束时间
				oneReport.setCellDates(cellWeeks);

			}
		} else if (CtCalcConsts.UNIT_TYPE_MONTH.equalsIgnoreCase(calcBody.getUnit())) {
			List<CtCalcDate> months = CtCalcDaysUtils.listCalcMonths(fromDate, toDate);
			for (CtCalcDate whichDate : months) {
				
				String fromDateDay = CtDateUtils.dateToString(whichDate.getFromDate(), CtDateUtils.YYYY_MM_DD);
				String toDateDay = CtDateUtils.dateToString(whichDate.getToDate(), CtDateUtils.YYYY_MM_DD);
				
				List<CtCalcDate> cellMonths = CtCalcDaysUtils.listCalcMonths(fromDateDay, todayDate);
				if(cellMonths.size() > 6) {
					cellMonths = new ArrayList<>(cellMonths.subList(0, 6));
				}
				
				CtRetentionsReport oneReport = this.copyBody(calcBody);
				calcReports.add(oneReport);

				oneReport.setWhichDay(fromDateDay);
				oneReport.setMaxCellIndex(cellMonths.size());

				// 本cellDay对应的第一事件的开始与结束日期
				oneReport.setTheFirstEventFromDate(fromDateDay);
				oneReport.setTheFirstEventToDate(toDateDay);

				// 本ROW的所有Cell的Date开始与结束时间
				oneReport.setCellDates(cellMonths);
			}
		}

		log.info("calcReports={}", JSON.toJSONString(calcReports));

		return calcReports;

	}

	public CtRetentionsReport copyBody(CtRetentionsCalcBody body) {
		CtRetentionsReport oneReport = new CtRetentionsReport();
		oneReport.setAppId(body.getAppId());
		oneReport.setBookmarkId(body.getBookmarkId());
		oneReport.setByEvents(body.getByEvents());
		oneReport.setByFields(body.getByFields());
		oneReport.setDuration(body.getDuration());
		oneReport.setFilter(body.getFilter());
		oneReport.setFirstEvent(body.getFirstEvent());
		oneReport.setFromDate(body.getFromDate());
		oneReport.setIsWastage(body.getIsWastage());
		oneReport.setLastZero(body.getLastZero());
		oneReport.setMeasures(body.getMeasures());
		oneReport.setRequestId(body.getRequestId());
		oneReport.setRollupDate(body.getRollupDate());
		oneReport.setSecondEvent(body.getSecondEvent());
		oneReport.setShowZeroDay(body.getShowZeroDay());
		oneReport.setSubjectId(body.getSubjectId());
		oneReport.setSubTaskType(body.getSubTaskType());
		oneReport.setToDate(body.getToDate());
		oneReport.setUnit(body.getUnit());
		oneReport.setUserUnit(body.getUserUnit());
		return oneReport;
	}

}
